#============================================================
#    Animation Canvas
#============================================================
# - datetime: 2023-01-08 14:06:21
#============================================================
## 动画画布
##
##用于播放动画，向这个节点添加 [AnimatedSprite2D] / [AnimatedSprite3D] / [AnimationPlayer]
class_name AnimationCanvas
extends Node2D


signal played(animation: StringName)


#============================================================
#  代理节点
#============================================================
class AbstractAgent:
	
	var host
	
	func _init(host) -> void:
		self.host = host
	
	func get_host():
		return host
	
	func has_animation(animation: StringName) -> bool:
		return false
	
	func play(animation: StringName):
		pass
	
	func stop():
		pass
	
	func get_animation_time(animation: StringName) -> float:
		return 0.0


class AgentAnimatedSprite extends AbstractAgent:
	
	func get_animation_time(animation: StringName) -> float:
		var animated_sprite = get_host()
		var count = animated_sprite.frames.get_frame_count(animation)
		var speed = 1.0 / animated_sprite.frames.get_animation_speed(animation)
		return speed * count / animated_sprite.speed_scale
	
	func has_animation(animation: StringName) -> bool:
		return get_host().frames.has_animation(animation)
	
	func play(animation):
		get_host().play(animation)
	
	func stop():
		get_host().stop()


class AgentAnimationPlayer extends AbstractAgent:
	
	func get_host() -> AnimationPlayer:
		return super.get_host() as AnimationPlayer
	
	func has_animation(animation) -> bool:
		return get_host().has_animation(animation)
	
	func play(animation):
		get_host().play(animation)
	
	func stop():
		get_host().stop()
	
	func get_animation_time(animation: StringName) -> float:
		var anim := get_host().get_animation(animation) as Animation
		return anim.length / get_host().playback_speed


## 播放动画的目标节点
@export_node_path(AnimatedSprite2D, AnimatedSprite3D, AnimationPlayer)
var target : NodePath 
## 自动搜索子节点是否有动画节点，如果指定了 [member target] 属性，则不会自动搜索
@export
var auto_search : bool = true


var _agent : AbstractAgent


#============================================================
#  SetGet
#============================================================
func get_target() -> Node:
	return _agent.get_host()

func get_animation_time(animation: StringName) -> float:
	return _agent.get_animation_time(animation)

func has_animation(animation: StringName) -> bool:
	return _agent.has_animation(animation)


#============================================================
#  内置
#============================================================
func _enter_tree() -> void:
	var node : Node
	if target != ^"":
		node = get_node(target)
	else:
		if auto_search:
			for child in get_children():
				if (child is AnimatedSprite2D 
					or child is AnimatedSprite3D 
					or child is AnimationPlayer
				):
					node = child
					break
	
	if node is AnimatedSprite2D or node is AnimatedSprite3D:
		_agent = AgentAnimatedSprite.new(node)
	elif node is AnimationPlayer:
		_agent = AgentAnimationPlayer.new(node)
	else:
		printerr("没有选中可播放动画的节点")


#============================================================
#  自定义
#============================================================
func play(animation: StringName):
	_agent.play(animation)
	self.played.emit(animation)


func stop():
	_agent.stop()

